//
//  TransformObject.m
//  CompGraf2
//
//  Created by Juan Niosi on 31/08/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "TransformObject.h"

@implementation TransformObject
@synthesize position, rotation, scale, name, children, parent;

- (id)init
{
    self = [super init];
    if (self)
    {
        GLfloat *pos = malloc(sizeof(GLfloat)*3);
        pos[0] = 0.0f;
        pos[1] = 0.0f;
        pos[2] = 0.0f;
        
        position = pos;
        
        GLfloat *rot = malloc(sizeof(GLfloat)*3);
        rot[0] = 0.0f;
        rot[1] = 0.0f;
        rot[2] = 0.0f;
        
        rotation = rot;
        
        GLfloat *scl = malloc(sizeof(GLfloat)*3);
        scl[0] = 1.0f;
        scl[1] = 1.0f;
        scl[2] = 1.0f;
        
        scale = scl;
        
        children = [[NSMutableArray alloc] init];
        self.parent = NULL;
    }
    
    return self;
}

- (void)applyTransform:(Engine *)engine
{
    [engine set_transform];
    
    [engine translate:position];
    [engine rotate:rotation];
    [engine scale:scale];
}

- (void)resetTransform:(Engine *)engine
{
    [engine reset_transform];
}

- (void)translate:(GLfloat *)mov
{
    position[0] += mov[0];
    position[1] += mov[1];
    position[2] += mov[2];
}

- (void)rotate:(GLfloat *)rot
{
    rotation[0] += rot[0];
    rotation[1] += rot[1];
    rotation[2] += rot[2];
}

- (void)scale:(GLfloat *)factors
{
    scale[0] += factors[0];
    scale[1] += factors[1];
    scale[2] += factors[2];
}

- (void)translateX:(GLfloat)mov
{
    position[0] += mov;
}

- (void)translateY:(GLfloat)mov
{
    position[1] += mov;
}

- (void)translateZ:(GLfloat)mov
{
    position[2] += mov;
}

- (void)rotateX:(GLfloat)rot
{
    rotation[0] += rot;
}

-(void)rotateY:(GLfloat)rot
{
    rotation[1] += rot;
}

- (void)rotateZ:(GLfloat)rot
{
    rotation[2] += rot;
}

- (void)scaleX:(GLfloat)x
{
    scale[0] *= x;
}

-(void)scaleY:(GLfloat)y
{
    scale[1] *= y;
}

- (void)scaleZ:(GLfloat)z
{
    scale[2] *= z;
}

- (void)scaleBy:(GLfloat)factor;
{
    scale[0] *= factor;
    scale[1] *= factor;
    scale[2] *= factor;
}
- (GLfloat *)forward
{
    GLfloat *fwd = malloc(sizeof(GLfloat)*3);
    fwd[0] = 0.0f;
    fwd[1] = 0.0f;
    fwd[2] = 1.0f;
    
    //TODO
    
    return fwd;
}

- (void)addChild:(TransformObject *)object
{
    if (object == nil)
    {
        NSLog(@"Trying to add null child to object %@", name);
        return;
    }
    object.parent = self;
    [children addObject:object];
}

- (TransformObject *)getChild:(NSString *)childName
{
    for (TransformObject *child in children)
    {
        if ([child.name isEqualToString:childName])
            return child;
    }
    
    return nil;
}

- (BOOL)removeChild:(NSString *)childName
{
    for (TransformObject *child in children)
    {
        if ([child.name isEqualToString:childName])
        {
            child.parent = NULL;
            [children removeObject:child];
            return true;
        }
    }
    return false;
}

- (Vector3*)posToVec3
{
    return [[Vector3 alloc] init:position[0] :0 :position[2]];
}

- (GLfloat *)getWorldPosition:(GLfloat *)pos
{
    GLfloat *parentPos = malloc(sizeof(GLfloat)*3);
    parentPos[0] = position[0] + pos[0];
    parentPos[1] = position[1] + pos[1];
    parentPos[2] = position[2] + pos[2];
    if (parent != NULL)
    {
        return [parent getWorldPosition:parentPos];
    }
    
    return parentPos;
}

-(GLfloat)getDistance:(GLfloat *)from
{
    float xDist = position[0] - from[0];
    float yDist = position[1] - from[1];
    float zDist = position[2] - from[2];
    
    return sqrtf(xDist*xDist + yDist*yDist + zDist*zDist);
}

-(GLfloat)getSqrDistance:(GLfloat *)from
{
    float xDist = position[0] - from[0];
    float yDist = position[1] - from[1];
    float zDist = position[2] - from[2];
    
    return xDist*xDist + yDist*yDist + zDist*zDist;
}

- (void)dealloc
{
    [name release];
    free(position);
    free(rotation);
    free(scale);
    [children release];
    [parent release];
    
    [super dealloc];
}
@end
